package com.linwen.javase.collection;


import org.junit.Test;

import java.util.*;

/**
 * @author : linwen
 * @date : 上午12:11 2021/7/22
 */
public class CollectionTest {
    //向collection接口中添加的元素都将被看作object类型，
    //自定义对象，需要重写equals


    //集合的常用方法
    @Test
    public void test1(){
        Collection collection = new ArrayList();
        //添加元素
        collection.add(123);
        collection.add(124);
        collection.add(456);
        collection.add("hello");
        //是否包含 调用对西那个的equals方法
        System.out.println("是否包含123"+collection.contains(123));
        Collection coll2 = Arrays.asList(123,456);
        //是否包含集合中所有的元素
        System.out.println("是否包含123，456"+collection.containsAll(coll2));
        //移除元素
        System.out.println("移除 hello"+collection.remove("hello"));
        //集合的交集
        System.out.println(collection.retainAll(coll2));
        System.out.println("交集为"+collection);
        //
        System.out.println("移除所有"+collection.removeAll(coll2));

        System.out.println(collection);
        collection.clear();
        System.out.println("集合最终大小"+collection.size());

    }

    //集合和数组相互转换
    @Test
    public void test2(){
        //数组转集合
        List<String> strings = Arrays.asList(new String[]{"h", "e", "l", "l", "o"});
        //集合转数组
        Object[] objects = strings.toArray();
        for (int i = 0; i < objects.length; i++) {
            System.out.print(objects[i]);
        }
    }
    //迭代器获取集合元素
    @Test
    public void test3(){
        //迭代器转为容器而生，目的就是为了迭代获取容器中的所有元素
        //迭代器的默认游标在第一个元素之前
        //内部就两个方法 hasNext()/next()/remove
        Collection collection = new ArrayList(Arrays.asList(new String[]{"h", "e", "l", "l", "o"}));
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            if("l".equals(next)){
                iterator.remove();
            }else{
                System.out.print(next);
            }
        }
        ArrayList collection2 = new ArrayList(Arrays.asList(new String[]{"h", "e", "l", "l", "o"}));
        for (int i = 0; i < collection2.size(); i++) {
            System.out.print(collection2.get(i));
        }
    }

    //ArrayList的常用方法
    /*
    * 增
    * 删
    * 查
    * 改
    * 大小
    * 遍历
    * */
    @Test
    public void test4(){
        ArrayList arrayList = new ArrayList();
        //增
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        System.out.println(arrayList);
        //删  重载了两种方法  根据索引删除&根据元素对象删除
        arrayList.remove(2);
        arrayList.remove(new Integer(2));
        System.out.println(arrayList);
        //查  根据元素下标查找
        Object o = arrayList.get(0);
        System.out.println(o);
        //改  根据元素下标修改
        arrayList.set(0,0);
        System.out.println(arrayList);
        //长度/大小
        System.out.println(arrayList.size());
        //循环   1：迭代器
        //      2：for循环
        Iterator iterator = arrayList.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next()+"   ");
        }
        for(Object o1:arrayList){
            System.out.print(o1+ "  ");
        }

        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        System.out.println(linkedList.get(0));
    }

    //Set
    /*
    * set的实现有HashSet  LinkedHashSet
    *           TreeSet
    * */
    @Test
    public void test5(){
        Set set1 = new HashSet();
        set1.add(111);
        set1.add(222);
        //自定义类的添加，需要重写hashCode方法和equals方法
        set1.add(new User("Tom",12));
        set1.add(new User("Jim",23));
        set1.add(new User("Jim",23));
        Iterator iterator = set1.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }


        System.out.println("*********************");
        //LinkedHashSet 维护了两个指针，记录元素添加的顺序
        Set set2 = new LinkedHashSet();
        set2.add(111);
        set2.add(222);
        //自定义类的添加，需要重写hashCode方法和equals方法
        set2.add(new User("Tom",12));
        set2.add(new User("Jim",23));
        set2.add(new User("Jim",23));

        Iterator iterator2 = set2.iterator();
        while (iterator2.hasNext()){
            System.out.println(iterator2.next());
        }


        System.out.println("********************");

        Set set3 = new TreeSet();
//        set3.add(111);
//        set3.add(222);
        //treeSet只能添加同一个类的元素，因为treeSet需要调用类的compare，比较元素大小，进行排序
        //treeSet默认排序
        //TreeSet排序需要实现CompareTo或者compare方法，不再根据equals方法
        set3.add(new User("Tom",12));
        set3.add(new User("Jim",25));
        set3.add(new User("Jim",23));
        Iterator iterator3 = set3.iterator();
        while (iterator3.hasNext()){
            System.out.println(iterator3.next());
        }
        System.out.println("____________________________________");
        //TreeSet compare另一种写法，以年龄comp排序，通常用作自定义排序
        Comparator com = new Comparator() {
            @Override
            public int compare(Object o1,Object o2) {
                User u1 = (User)o1;
                User u2 = (User)o2;
                return Integer.compare(u1.getAge(),u2.getAge());
            }
        };
        Set set4 = new TreeSet(com);
        set4.add(new User("Tom",12));
        set4.add(new User("Jim",25));
        set4.add(new User("Jim",23));
        Iterator iterator4 = set4.iterator();
        while (iterator4.hasNext()){
            System.out.println(iterator4.next());
        }

    }
    class User implements Comparable {
        private String name;
        private int age;

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof User)) return false;
            User user = (User) o;
            return age == user.age &&
                    Objects.equals(name, user.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }

        @Override
        public int compareTo(Object o) {
            if (o instanceof User) {
                User user = (User) o;
                return this.name.compareTo(user.getName());
            } else {
                throw new RuntimeException("类型转换错误");
            }
        }

    }


    //Map
    /*
    * 常用方法：
    * 添加：put  putall
    * 修改：put相同key，value不同
    * 删除指定key：remove
    * 清空：clear
    * 获取：get
    * 包含key：containsKey
    * 包含value：containsValue
    *
    * 遍历方法
    * */
    @Test
    public void test6(){
        Map map = new HashMap();
        //添加
        map.put("zhangsan",123);
        map.put("lisi",234);
        map.put("wangwu",345);
        System.out.println(map);
        map.put("lisi",456);
        System.out.println(map);
        Map map2 = new HashMap();
        map2.put("zhaoliu",576);
        map.putAll(map2);
        System.out.println(map);
        map.remove("lisi");
        System.out.println(map);
        System.out.println(map.get("zhangsan"));
        System.out.println(map.containsKey("zhangsan"));
        System.out.println(map.containsValue(123));
        //map.clear();
        System.out.println(map);
        System.out.println("=========================");

        Set entrySet = map.entrySet();
        Set keySet = map.keySet();
        Collection values = map.values();
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            System.out.println(entry.getKey()+"---------"+entry.getValue());
        }

    }

    //定义一个线程安全的集合
    @Test
    public void test7(){
        List<Object> list = Collections.synchronizedList(new ArrayList<>());

    }
}
